package com.boarsoft.boar.app.biz;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.boarsoft.bean.ReplyInfo;
import com.boarsoft.boar.app.AppBiz;
import com.boarsoft.boar.app.AppFileBiz;
import com.boarsoft.boar.app.AppInstBiz;
import com.boarsoft.boar.app.AppLibBiz;
import com.boarsoft.boar.dir.DirBiz;
import com.boarsoft.boar.entity.AppFile;
import com.boarsoft.boar.entity.AppInfo;
import com.boarsoft.boar.entity.AppInst;
import com.boarsoft.boar.entity.AppInstFile;
import com.boarsoft.boar.entity.AppLib;
import com.boarsoft.boar.entity.DirInfo;
import com.boarsoft.boar.file.FileBiz;
import com.boarsoft.common.Util;
import com.boarsoft.common.dao.PagedResult;
import com.boarsoft.hibernate.biz.SimpleBizImpl;

public abstract class AppBaseBizImpl extends SimpleBizImpl implements AppBiz {
	@Autowired
	protected DirBiz dirBiz;
	@Autowired
	protected AppInstBiz appInstBiz;
	@Autowired
	protected AppLibBiz appLibBiz;
	@Autowired
	protected AppFileBiz appFileBiz;
	@Autowired
	protected FileBiz fileBiz;

	// protected Class<? extends AppInfo> clazz;

	@Override
	@Transactional
	public void delete(String id) {
		StringBuilder sb = new StringBuilder();
		// 删除与节点的关联
		sb.setLength(0);
		sb.append("delete from ").append(AppInst.class.getName())//
				.append(" where appId='").append(id).append("'");
		dao.executeUpdate(sb.toString());
		// 删除与文件的关系
		sb.setLength(0);
		sb.append("delete from ").append(AppFile.class.getName())//
				.append(" where appId='").append(id).append("'");
		dao.executeUpdate(sb.toString());
		// 删除应用实例与文件的关联系
		sb.setLength(0);
		sb.append("delete from ").append(AppInstFile.class.getName())//
				.append(" where appId='").append(id).append("'");
		dao.executeUpdate(sb.toString());
		// 删除与库包的关联
		sb.setLength(0);
		sb.append("delete from ").append(AppLib.class.getName())//
				.append(" where appId='").append(id).append("'");
		dao.executeUpdate(sb.toString());
		// 但不删除应用本身
		// dao.delete(AppInfo.class, id);
	}

	@Override
	@Transactional(readOnly = true)
	public PagedResult<AppInfo> list(String dirId, String projId, String code, String name, String key, String orderBy,
			int pageNo, int pageSize) {
		StringBuilder sb = new StringBuilder();
		if (Util.strIsNotEmpty(dirId)) {
			sb.append(" and d.parentId='").append(dirId).append("')");
		} else {
			sb.append(")");
		}
		if (Util.strIsNotEmpty(projId)) {
			DirInfo projDir = dao.get(DirInfo.class, projId);
			if ("/".equals(projDir.getPath())) {
				sb.append(" and exists (select id from DirInfo where type=");
				sb.append(DirInfo.TYPE_APP).append(" and id=a.id and path like '");
				sb.append(projDir.getPath()).append(projId).append("%')");
			} else {
				sb.append(" and exists (select id from DirInfo where type=");
				sb.append(DirInfo.TYPE_APP).append(" and id=a.id and path like '");
				sb.append(projDir.getPath()).append("/").append(projId).append("%')");
			}
		}
		if (Util.strIsNotEmpty(key)) {
			sb.append(" and (a.code like '%").append(key);
			sb.append("%' or a.memo like '%").append(key);
			sb.append("%' or a.name like '%").append(key);
			sb.append("%') ");
		}
		if (Util.strIsNotEmpty(code)) {
			sb.append(" and a.code like '%").append(code).append("%') ");
		}
		if (Util.strIsNotEmpty(name)) {
			sb.append(" and a.name like '%").append(name).append("%') ");
		}

		String totalSql = new StringBuilder().append("select count(a.id) from ").append(AppInfo.class.getName())
				.append(" a where EXISTS (select d.id from ").append(DirInfo.class.getName()).append(" d where d.id=a.id ")
				.append(sb).toString();
		int total = dao.getTotal(totalSql);
		if (Util.strIsNotEmpty(orderBy)) {
			// String ob = Util.array2str(("e." + orderBy).replaceAll(",",
			// ",").split(","), ",");
			sb.append(" order by ").append(orderBy);
		} else {
			sb.append(" order by a.name");
		}
		//
		String hql = new StringBuilder().append("select a from ").append(AppInfo.class.getName())
				.append(" a where EXISTS (select d.id from ").append(DirInfo.class.getName()).append(" d where d.id=a.id ")
				.append(sb).toString();
		List<AppInfo> lt = dao.list(hql, AppInfo.class, pageNo, pageSize);
		return new PagedResult<AppInfo>(total, lt, pageNo, pageSize);
	}

	@Override
	@Transactional
	public ReplyInfo<Object> add(DirInfo d, AppInfo a) {
		ReplyInfo<Object> ro = dirBiz.add(d);
		if (ro.isSuccess()) {
			a.setId(d.getId());
			dao.save(a);
			return ReplyInfo.SUCCESS;
		}
		return ro;
	}

	@Override
	@Transactional
	public void update(DirInfo d, AppInfo a) {
		if (d != null) {
			dirBiz.update(d);
		}
		dao.merge(a);
	}

	@Override
	@Transactional(readOnly = true)
	public AppInfo find(String code) {
		StringBuilder sb = new StringBuilder();
		sb.append(" and code='").append(code).append("'");
		return dao.find(AppInfo.class, sb.toString());
	}

	@Override
	@Transactional(readOnly = true)
	public AppInfo find(String code, String ver) {
		StringBuilder sb = new StringBuilder();
		sb.append(" and code='").append(code).append("'");
		sb.append(" and ver ='").append(ver).append("'");
		return dao.find(AppInfo.class, sb.toString());
	}

	@Override
	@Transactional
	public boolean start(String ids) {
		String[] a = ids.split(",");
		for (String id : a) {
			AppInfo o = dao.get(AppInfo.class, id);
			o.setStatus(AppInfo.STATUS_INUSE);
			dirBiz.start(id);
		}
		return true;
	}

	@Override
	@Transactional
	public boolean stop(String ids) {
		String[] a = ids.split(",");
		for (String id : a) {
			AppInfo o = dao.get(AppInfo.class, id);
			o.setStatus(AppInfo.STATUS_NOUSE);
			dirBiz.stop(id);
		}
		return true;
	}

	@Override
	@Transactional(readOnly = true)
	public AppInfo find2(String code, String projId) {
		StringBuilder sb = new StringBuilder();
		sb.append(" and code='").append(code).append("'");
		sb.append(" and projId='").append(projId).append("'");
		return (AppInfo) dao.find(AppInfo.class, sb.toString());
	}

}